/**
 * 自动化提审脚本
 * @todo
 * 1. 检查是否有版本在审核中
 * 2. 提醒上传失败找到钉钉群
 * 3. 提审成功通知到钉钉群
 * 4. 发送体验版二维码到钉钉群
 * @author <syoryken@sina.com> [https://gitee.com/Syory]
 */

const { URL } = require('url');
const puppeteer = require('puppeteer');
const terminalImgQrcode = require('terminal-img-qrcode');
const { program } = require('commander');
const { sleep, post, get, createParams } = require('./utils');

program
    .option('-v, --upversion <type>', '提审版本号', 'v1.0.0')
    .option('-d, --updescription <type>', '提审版本描述', '版本更新');

program.parse(process.argv);

async function loginWx() {
    const options = program.opts();
    const browser = await puppeteer.launch({
        headless: true, // false显示无头浏览器
        defaultViewport: {
            width: 1200,
            height: 600
        }
    });
    const context = await browser.createIncognitoBrowserContext();
    const page = await context.newPage();
    const wxHost = 'https://mp.weixin.qq.com/';

    page.once('load', async () => {
        async function saveQrcode(response) {
            if (response.url().indexOf('/cgi-bin/scanloginqrcode?action=getqrcode') > -1) {
                terminalImgQrcode(await response.buffer());
                page.off('response', saveQrcode);
            }
        }
        page.on('response', saveQrcode);
    });
    page.once('error', async err => {
        await browser.close();
        process.stderr.write(err);
        process.exit(1);
    });

    await page.goto(wxHost);

    let locked = true;
    page.once('load', async () => {
        locked = false;
        console.log(`--------登录成功--------`);
        const urlObj = new URL(page.url(), wxHost);
        const token = urlObj.searchParams.get('token')

        // 进入提交页面
        page.once('load', async () => {
            await sleep(2);

            console.log(`--------开始获取小程序版本内容--------`);

            const client = await page.target().createCDPSession();
            const cookie = (await client.send('Network.getAllCookies')).cookies.map(item => {
                return `${item.name}=${item.value}`;
            }).join(';');

            // 获取版本内容
            const historyListUrl = `${wxHost}wxamp/cgi/route?${createParams({
                path: `/wxopen/wacodepage?${createParams({
                    action: 'getcodepage',
                    f: 'json',
                    token,
                    lang: 'zh_CN'
                })}`,
                token,
                lang: 'zh_CN'
            })}`;
            const historyListRes = await get(historyListUrl, { 'cookie': cookie });

            if (!historyListRes) {
                await browser.close();
                process.stderr.write('获取历史小程序列表失败', historyListRes);
                process.exit(1);
            }

            if (!historyListRes.code_data) {
                await browser.close();
                process.stderr.write('获取历史小程序列表失败', historyListRes);
                process.exit(1);
            }

            const codeData = JSON.parse(historyListRes.code_data);
            const infoList = codeData.develop_info.info_list;

            // 目前通过版本号模糊匹配
            const submitVersion = infoList.find(item => item.basic_info.version === options.upversion);

            if (!submitVersion) {
                // TODO::通过钉钉群提醒没有找到群
                await browser.close();
                process.stderr.write('未找到要提交审核的版本');
                process.exit(1);
            }

            console.log(`--------开始提交代码--------`);
            console.log(`【开始提交代码】提审版本: ${submitVersion.basic_info.version}, 版本描述: ${submitVersion.basic_info.describe}, 提交人: ${submitVersion.basic_info.nick_name}`);

            // 获取auto_id
            const autoIdUrl = `${wxHost}wxamp/cgi/route?${createParams({
                path: `/wxopen/wadevelopcode?${createParams({
                    action: 'get_class',
                    f: 'json',
                    token,
                    lang: 'zh_CN',
                    openid: submitVersion.basic_info.open_id,
                    user_name: submitVersion.basic_info.nick_name
                })}`,
                token,
                lang: 'zh_CN'
            })}`;
            const autoIdRes = await get(autoIdUrl, { 'cookie': cookie });

            if (!autoIdRes) {
                await browser.close();
                process.stderr.write('autoid获取失败');
                process.exit(1);
            }

            const publicKeyInfo = JSON.parse(autoIdRes.public_key_info);
            const submitUrl = `${wxHost}wxamp/cgi/route?${createParams({
                path: `/wxopen/wadevelopcode?${createParams({
                    action: 'submit_check'
                })}`,
                token,
                lang: 'zh_CN'
            })}`

            // 提交审核
            const submitRes = await post(submitUrl, {
                ticket: 'qrcheckTicket',
                openid: submitVersion.basic_info.open_id,
                auto_id: publicKeyInfo.auto_id,
                version_desc: options.updescription, // 版本描述
                speedup_audit: 0,
                speedup_type: '修复漏洞',
                speedup_desc: '',
                encrypted_username: '',
                encrypted_password: '',
                remark: '',
                feedback_info: '',
                feedback_status: 1,
                only_run_wxwork: 0,
                argue_item: '',
                preview_info: '{"pic_id_list":[],"video_id_list":[]}',
                feedback_stuff: ''
            }, { 'cookie': cookie });

            if (submitRes && Number(submitRes.ret) === 0) {
                console.log('提交代码成功');
            } else {
                await browser.close();
                process.stderr.write(submitRes);
                process.exit(1);
            }

            await browser.close();
            process.exit(0);
        });

        await page.goto(`${wxHost}wxamp/wacodepage/getcodepage?token=${token}&lang=zh_CN`);
    });

    // 60s自动结束
    setTimeout(async () => {
        if (locked) {
            await browser.close();
            process.stderr.write('二维码超时');
            process.exit(1);
        }
    }, 60 * 1000);
}

loginWx()
    .catch(err => {
        console.log(err);
        console.log('登陆重试');
        loginWx()
            .catch(err => {
                console.log(err);
                process.exit(1);
            })
    })